package cn.dlc.com.config.advice;

import cn.dlc.com.config.response.ResponseVO;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @Author: dlc
 * @Date: 2021/8/2 - 16:35
 * 通用响应处理类，如果响应数据不是ResponseVO格式的，那么封装一下
 */

@RestControllerAdvice
public class ResponseVOFormatHandler implements ResponseBodyAdvice<Object> {

   @Override
   public boolean supports(MethodParameter methodParameter,
                           Class<? extends HttpMessageConverter<?>> aClass) {

       // 判断请求是否需要包装，默认true
       Class<?> clazz = methodParameter.getNestedParameterType();

       // 判断返回类的类型clazz.isAssignableFrom(ResponseVO.class)
       // 如果是ResponseVO，那么就通过
       if(ResponseVO.class.getName().equals(clazz.getName())) {
           // 通过
           return false;
       } else if("org.springframework.http.ResponseEntity".equals(clazz.getName())) {
           // swagger地址的时候是这种返回类型（swagger-starter：3.0.2；swagger2.9.2都是这个类型）
           return false;
       }
       // 不通过，需要二次封装
       return true;
   }

    /**
     * 不符合的话进入当前方法，进行二次封装
     * @param o controller方法返回的对象
     * @param methodParameter
     * @param mediaType
     * @param aClass
     * @param serverHttpRequest
     * @param serverHttpResponse
     * @return
     */
   @Override
   public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
                                 MediaType mediaType,
                                 Class<? extends HttpMessageConverter<?>> aClass,
                                 ServerHttpRequest serverHttpRequest,
                                 ServerHttpResponse serverHttpResponse) {

       // 需要先判断一下返回的状态吗？？？

       // 如果是null，直接返回
       System.out.println("二次封装返回参数");

       return null == o? ResponseVO.success(null): ResponseVO.success(o);
   }
}